package com.jingdianjichi.auth.domain.service.Impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.jingdianjichi.auth.common.enums.AuthUserStatusEnum;
import com.jingdianjichi.auth.common.enums.IsDeletedFlagEnum;
import com.jingdianjichi.auth.domain.bo.AuthUserBO;
import com.jingdianjichi.auth.domain.convert.AuthUserBOConvert;
import com.jingdianjichi.auth.domain.redis.RedisUtil;
import com.jingdianjichi.auth.domain.service.AuthUserDomainService;
import com.jingdianjichi.auth.infra.bastic.entity.*;
import com.jingdianjichi.auth.infra.bastic.service.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.gson.GsonProperties;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.lang.model.element.VariableElement;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * ClassName:UserDomainServiceImpl
 * Package:com.jingdianjichi.auth.domain.service.Impl
 * Description:
 *
 * @Author fst
 * @Create 2024/10/10 13:27
 * @Version 1.0
 */

@Slf4j
@Service
public class AuthUserDomainServiceImpl implements AuthUserDomainService
{
    private static final String NORMAL_KEY ="normal_user";

    private static final String authRolePrefix="auth.role";

    private static final String authPermissionPrefix="auth.permission";
    @Resource
    private AuthUserService authUserService;

    @Resource
    private AuthPermissionService authPermissionService;

    @Resource
    private AuthRolePermissionService authRolePermissionService;

    @Resource
    private AuthRoleService authRoleService;

    @Resource
    private AuthUserRoleService authUserRoleService;

    @Resource
    private RedisUtil redisUtil;

    private static final String LOGIN_PREFIX ="loginCode";


    @Transactional(rollbackFor = Exception.class)
    @SneakyThrows
    public  void add(AuthUserBO authUserBO)
    {
        if(log.isInfoEnabled())
        {
            log.info("AuthUserDomainServiceImpl.add.Bo:{}", JSON.toJSONString(authUserBO));
        }

        AuthUser authUser= AuthUserBOConvert.INSTANCE.convertBOTOUser(authUserBO);
        //校验用户是否存在

        List<AuthUser> authUserList= authUserService.queryByCondition(authUser);

        if(authUserList.size()>0)
        {
            return ;
        }

        if (!StringUtils.isEmpty(authUser.getPassword()))
        {
            authUser.setPassword(SaSecureUtil.md5(authUser.getPassword()));
        }
        authUser.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
        authUser.setStatus(AuthUserStatusEnum.OPEN.getCode());



        authUser = authUserService.insert(authUser);

        AuthRole authRole=new AuthRole();
        authRole.setRoleKey(NORMAL_KEY);

        authRole = authRoleService.queryCondition(authRole);

        AuthUserRole authUserRole=new AuthUserRole();


        authUserRole.setUserId(authUser.getId());
        authUserRole.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
        authUserRole.setRoleId(authRole.getId());
        authUserRoleService.insert(authUserRole);

        String key = redisUtil.buildKey(authRolePrefix, authUser.getUserName());

        List<AuthRole> roleList =new LinkedList<>();
        roleList.add(authRole);

        redisUtil.set(key,new Gson().toJson(roleList));

        //查出相关的权限
        AuthRolePermission authRolePermission=new AuthRolePermission();
        authRolePermission.setRoleId(authRole.getId());
        List<AuthRolePermission> rolePermissionList = authRolePermissionService.queryByCondition(authRolePermission);

        List<Long> permissionIdList=new LinkedList<>();

        for (AuthRolePermission rolePermission : rolePermissionList) {
            permissionIdList.add(rolePermission.getPermissionId());
        }

        //更具id查权限

        List<AuthPermission> authPermissionList=authPermissionService.queryByIdList(permissionIdList);

        String permissionKey=redisUtil.buildKey(authPermissionPrefix,authUser.getUserName());

        redisUtil.set(permissionKey,new Gson().toJson(authPermissionList));

    }

    public void update(AuthUserBO authUserBO)
    {
        if(log.isInfoEnabled())
        {
            log.info("AuthAuthUserDomainServiceImpl.update.Bo:{}", JSON.toJSONString(authUserBO));
        }

        AuthUser authUser= AuthUserBOConvert.INSTANCE.convertBOTOUser(authUserBO);

        authUserService.update(authUser);
    }

    public void delete(AuthUserBO authUserBO)
    {
        if(log.isInfoEnabled())
        {
            log.info("AuthAuthUserDomainServiceImpl.delete.Bo:{}", JSON.toJSONString(authUserBO));
        }

        AuthUser authUser= AuthUserBOConvert.INSTANCE.convertBOTOUser(authUserBO);

        authUserService.delete(authUser);
    }

    public SaTokenInfo doLogin(String validCode)
    {
        String loginKey = redisUtil.buildKey(LOGIN_PREFIX, validCode);
        String openId=redisUtil.get(loginKey);
        if(StringUtils.isEmpty(openId))
        {
            return null;
        }

        AuthUserBO authUserBO=new AuthUserBO();
        authUserBO.setUserName(openId);
        this.add(authUserBO);
        StpUtil.login(openId);
        return StpUtil.getTokenInfo();
    }

    public AuthUserBO getUserInfo(AuthUserBO authUserBO)
    {
        AuthUser authUser=new AuthUser();
        authUser.setUserName(authUserBO.getUserName());

        List<AuthUser> authUserList =authUserService.queryByCondition(authUser);

        if(authUserList.size()==0)
        {
            return new AuthUserBO();
        }
        return AuthUserBOConvert.INSTANCE.convertUserTOBO(authUserList.get(0));
    }

    @Override
    public List<AuthUserBO> listUserInfoByIds(List<String> userNameList) {
        List<AuthUser> userlist =authUserService.listUserInfoByIds(userNameList);
        if(CollectionUtils.isEmpty(userlist))
        {
            return Collections.emptyList();
        }
        return AuthUserBOConvert.INSTANCE.convertUserTOBOlist(userlist);
    }
}
